#pragma once
#include <mutex>
#include <map>
#include <shared_mutex>
#include <thread>
#include <queue>
#include <vector>
#include <condition_variable>
#include "BondDetailData.h"
#include <uam/UserAccountManager.h>
const int	_RELEVANCEFILTERFIRST = 2;	//   2//相似一级
const int   _RELEVANCEFILTERSECOND = 1;	// 1//相似二级
const int   _RELEVANCEFILTERISSUER = 0;	//0//同发行人
class CPrimarySimilarEx : public QObject
{
	Q_OBJECT
public:
	CPrimarySimilarEx();
	~CPrimarySimilarEx();

	enum SimilarStatus { 
		emKeyIsEmpty = -3, 
		emHandleIsInvalid = -2, 
		emNotFindBond = -1, 
		emNotSimilar = 0, 
		emNotCache = 1, 
		emSuccess = 2, 
	};
	const int INVALID_BROKEDR_ID;

	struct SimilarCacheKey
	{
		std::string sCombondkey;
		int nType;
		int nSubType;

		SimilarCacheKey()
		{
			nType = _RELEVANCEFILTERSECOND;
			nSubType = 0;
		}

		SimilarCacheKey(std::string sCombondkey_p, int nType_p, int nSubType_p)
		{
			sCombondkey = sCombondkey_p;
			nType = nType_p;
			nSubType = nSubType_p;
		}

		bool operator<(const SimilarCacheKey& that) const
		{
			char szThis[128] = { 0 }, szThat[128] = { 0 };
			sprintf(szThis, "%s%d%d", sCombondkey.c_str(), nType, nSubType);
			sprintf(szThat, "%s%d%d", that.sCombondkey.c_str(), that.nType, that.nSubType);

			return strcmp(szThis, szThat) < 0;
		}
	};

public:
	bool loadNotifyCombondKey(int nRandKey, SimilarCacheKey& sk);
	int  loadSimilarEx(SimilarCacheKey& sk, std::vector<BrokerKey>& vec_idxs, std::vector<int>& vec_idx);
protected:
	bool isValidBond(SimilarCacheKey& sck, const CBondInfo* pInfo, const CBondInfo& currentInfo);
	bool isValidFstDay(const CBondInfo* pInfo);
	bool isValidExpire(int nType, const CBondInfo* pInfo, const CBondInfo& currentInfo);
	bool isValidSubType(const CBondInfo* pInfo, const CBondInfo& currentInfo);
	bool isValidRating(const CBondInfo* pInfo, const CBondInfo& currentInfo);
	bool isValidIndustry(const CBondInfo* pInfo, const CBondInfo& currentInfo);
	bool isValidIssuer(const CBondInfo* pInfo, const CBondInfo& currentInfo);//同发行人

	int  getTermData(const char* cTerm);//获取期限 返回日期

	void reGetSecondVaildData(std::vector<int>& vctCurrentBond, std::vector<BrokerKey>& vctCurrentBondValid);
	void reGetIssuerVaildData(const CBondInfo& bi_src, std::vector<int>& vctCurrentBond, std::vector<BrokerKey>& vctCurrentBondValid);
	bool insertIssuerWndKey(const char* bondKey, BrokerKey& stBondKey);
	void doBroadcast(SimilarCacheKey& sck);

	bool isHaveCache(SimilarCacheKey sck, std::map<SimilarCacheKey, std::vector<BrokerKey>>& map_cache, std::mutex& rw_lock_r);

	bool isQuering(SimilarCacheKey sck);

	bool getMarketReport(const char* bondKey, const char* cMarket, BrokerKey& stBondKey);

	void threadProc();

	SimilarCacheKey pop();
	void insertMapQueryData(SimilarCacheKey sck);
protected:
	std::map<SimilarCacheKey, std::vector<BrokerKey>> m_map_cache;
	std::map<SimilarCacheKey, std::vector<int>> m_map_idx_cache;
	std::mutex m_rw_cache;

	std::map<int, CBrokerUnit> m_mapBroker;

	std::mutex m_rw_quering;
	std::map<SimilarCacheKey, bool> m_map_quering;
	std::mutex			m_mutex_queue;
	std::queue<SimilarCacheKey> m_queue_query;

	std::thread*		   m_pDispatchMessageThread;	
	bool				   m_bStopDispatch;				//true表示停用分发线程

	std::condition_variable_any m_condition_pop;   //读取条件量

	std::mutex m_rw_notify_key;
	std::map<int, SimilarCacheKey> m_map_notify;

	void initialBroker();
	std::vector<CBrokerUnit> m_vctBroker;
public:
	void initial();
	static CPrimarySimilarEx& GetInstance();
signals:
	void notifyGetSimilarBond(int randomKey);
protected:
	bool getInitFlag() const { return m_bInitial; }
	bool m_bInitial;
};